from uuid import uuid4
from flask import Flask, jsonify, request
from blockchain import BlockChain

"""这里的flask应用模拟一个用户(矿工/节点)"""
app = Flask(__name__)
# 节点地址
node_identifier = str(uuid4()).replace('-', '')

# 实例化区块链类
blockchain = BlockChain()


# 去挖掘新的区块
@app.route('/mine', methods=['GET'])
def mine():
    last_block = blockchain.last_block  # 已存在的最新的区块
    last_proof = last_block['proof']
    # 模拟挖矿动作，如果挖掘到新的区块并返回新区块的工作量证明
    proof = blockchain.proof_of_work(last_proof)
    # 当前节点挖到新的区块，生成一个新的交易信息
    blockchain.new_transaction(
        sender='0',   # 发送者为0表明是新挖出的区块
        recipient=node_identifier,
        amount=1
    )
    # 把当前节点挖到的区块加入到区块链中
    block = blockchain.new_block(proof, None)
    # 返回响应数据
    response = {
        'message': '新的区块已经创建',
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash']
    }
    return jsonify(response), 200


# 通过双方转账产生的区块
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    # 接收post过来的json数据
    values = request.get_json()
    # 检查POST数据
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return '缺失参数', 400
    # 生成当前的交易信息
    blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    # 把当前的交易信息加入到区块链中
    blockchain.new_block()
    response = {'message': f'当前交易将会被加入到区块链中第 {index} 的位置'}
    return jsonify(response), 201


# 返回当前节点存储的整个区块链
@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain)
    }
    return jsonify(response), 200


# 注册节点
@app.route('/nodes/register', methods=['POST'])
def register_nodes():
    address = request.values.get('address')
    if address is None:
        return '缺失参数', 400
    blockchain.register_node(address)

    response = {
        'message': '新的节点已经被添加',
        'total_nodes': list(blockchain.nodes)
    }
    return jsonify(response), 201


# 解决冲突
@app.route('/nodes/resolve', methods=['GET'])
def consensus():
    replaced = blockchain.resolve_conflicts()
    if replaced:
        response = {
            'message': '发现有效更长链，我们自己的链已被替换为该链',
            'new_chain': blockchain.chain,
        }
    else:
        response = {
            'message': '我们的链是有效更长链',
            'chain': blockchain.chain
        }
    return jsonify(response), 200


if __name__ == '__main__':
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on')
    args = parser.parse_args()
    port = args.port
    print(node_identifier)
    app.run(host='127.0.0.1', port=port)










